#!/usr/bin/env php
<?php

require_once('tests/test-runners.php');
// delete_recursive, mkdir_full, tmpdir
require_once('include/file-utils.php');

$start_time = microtime(true);

array_shift($argv);
$test_restrict = empty($argv) ? null : $argv;
$sched = file('tests/test-schedule');

$passes = 0;
$fails  = 0;
$xfails = 0;
$skips  = 0;
$fixes  = 0;

$line = 0;

function sig_handler($signo)
{
	global $output;
	if ($signo == SIGINT) // Ctrl+C
	{
		echo $output, PHP_EOL;
		exit();
	}
}
// tick use required as of PHP 4.3.0
declare(ticks = 1);
pcntl_signal(SIGINT,  "sig_handler");

// Get a working folder for this run of tests
$workPath = tmpdir(null, 'ide-test-');

$single = false;
$full_output = false;
if ($test_restrict != null)
{
	$tmp = array_diff($test_restrict, array('-s', '--single'));
	if (count($tmp) != count($test_restrict))
	{
		$single = true;
		$full_output = true;
		$test_restrict = $tmp;
	}
	$tmp = array_diff($test_restrict, array('--full-output'));
	if (count($tmp) != count($test_restrict))
	{
		$full_output = true;
		$test_restrict = $tmp;
	}
}

foreach ($sched as $value)
{
	++$line;
	$value = preg_replace('/#.*$/', '', $value);
	$value = trim($value);
	if ($value == '')
		continue;
	$exp = explode(' ', $value);
	if (count($exp) != 2 && count($exp) != 4)
	{
		++$fails;
		echo "FAIL    bad schedule line %d\n";
	}
	$xfail  = $exp[0] == 'XFAIL';
	$tn     = $exp[1];
	// check against tests
	if ($test_restrict != null)
	{
		$skip = true;
		foreach ($test_restrict as $restriction)
		{
			if (fnmatch("*$restriction*", $tn))
			{
				$skip = false;
				break;
			}
		}
		if ($skip)
			continue;
	}

	// Create a temp folder for this test, and store it somewhere the test can see it too.
	$testWorkPath = "$workPath/$tn/";
	mkdir_full($testWorkPath);
	putenv("IDE_TEST_WORK_PATH=$testWorkPath");

	$runner = BaseRunner::createRunner($tn);
	$infile = isset($exp[2]) ? $exp[2] : '/dev/null';
	list($rc, $output) = $runner->run($infile);
	if ($rc == 0)
	{
		delete_recursive($testWorkPath);
		if (strpos($output, '___SKIP_TEST') !== false)
		{
			++$skips;
			echo "SKIP    $tn\n";
		}
		elseif ($xfail)
		{
			++$fixes;
			echo "FIXED   $tn\n";
		}
		else
		{
			++$passes;
			echo "PASS    $tn\n";
		}
	}
	else
	{
		if ($xfail)
		{
			delete_recursive($testWorkPath);
			++$xfails;
			echo "XFAIL   $tn\n";
		}
		else
		{
			++$fails;
			echo "FAIL    $tn\n";
			$lines = explode("\n", $output);
			if (count($lines) > 10 && !$full_output)
			{
				$tmpfile = tempnam("/tmp", "ide-test-");
				file_put_contents($tmpfile, "$output\n");
				echo "=== BEGIN OUTPUT TAIL ===\n";
				echo implode(PHP_EOL, array_slice($lines, -10)), PHP_EOL;
				echo "===  END OUTPUT TAIL  ===\n";
				echo "\tSee $tmpfile for further output.\n";
			}
			else
			{
				echo "=== BEGIN OUTPUT ===\n";
				echo "$output\n";
				echo "===  END OUTPUT  ===\n";
			}
		}
	}
	if ($single)
		break;
}

$end_time = microtime(true);
$duration = $end_time - $start_time;

printf("%4d tests passed in %4.3f seconds.\n", $passes, $duration);
if ($fails > 0)
{
	printf("%4d tests failed in %4.3f seconds.\n", $fails, $duration);
	echo "\tSee working directory '$workPath'.\n";
}
else
{
	delete_recursive($workPath);
}
if ($xfails > 0)
	printf("%4d xfails.\n", $xfails);
if ($fixes > 0)
	printf("%4d fixes.\n", $fixes);
if ($skips > 0)
	printf("%4d tests skipped.\n", $skips);
exit($fails > 0 ? 1 : 0);

